package me.yricky.cov_spectrum.model

import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import me.yricky.cov_spectrum.app
import me.yricky.cov_spectrum.model.ApiConstant.PK_AA_I
import me.yricky.cov_spectrum.model.ApiConstant.PK_AA_M
import me.yricky.cov_spectrum.model.ApiConstant.PK_ACCESS_KEY
import me.yricky.cov_spectrum.model.ApiConstant.PK_COUNTRY
import me.yricky.cov_spectrum.model.beans.*
import me.yricky.cov_spectrum.model.ApiConstant.PK_DATE_FROM
import me.yricky.cov_spectrum.model.ApiConstant.PK_DATE_TO
import me.yricky.cov_spectrum.model.ApiConstant.PK_FIELDS
import me.yricky.cov_spectrum.model.ApiConstant.PK_HOST
import me.yricky.cov_spectrum.model.ApiConstant.PK_NEXT_CLADE
import me.yricky.cov_spectrum.model.ApiConstant.PK_NUC_I
import me.yricky.cov_spectrum.model.ApiConstant.PK_NUC_M
import me.yricky.cov_spectrum.model.ApiConstant.PK_PANGO
import me.yricky.cov_spectrum.model.ApiConstant.PK_VARIANT_QUERY
import me.yricky.cov_spectrum.model.ApiConstant.PV_FIELD_DATE
import me.yricky.cov_spectrum.model.ApiConstant.PV_FIELD_PANGO
import me.yricky.cov_spectrum.model.ApiConstant.PV_HOST_HUMAN

object ApiModel {


    suspend fun getCountries():Result<List<CountryData>> = let{
        app.httpClient.request {
            url("https://cov-spectrum.org/api/v2/resource/country")
            method = HttpMethod.Get
        }.body()
    }

    suspend fun getCollectionItem():Result<List<CollectionItem>> = kotlin.runCatching{
        app.httpClient.request {
            url("https://cov-spectrum.org/api/v2/resource/collection")
            method = HttpMethod.Get
        }.body()
    }

    suspend fun getRefGene():Result<GenomeBean> = kotlin.runCatching{
        app.httpClient.request {
            url("https://cov-spectrum.org/api/v2/resource/reference-genome")
            method = HttpMethod.Get
        }.body()
    }

    suspend fun getPangoLineageAlias():Result<List<PangoLineageAliasItem>> = kotlin.runCatching{
        app.httpClient.request {
            url("https://cov-spectrum.org/api/v2/resource/pango-lineage-alias")
            method = HttpMethod.Get
        }.body()
    }

    suspend fun getPangoLineage(
        accessKey:String
    ):Result<CommonApiBean<List<PangoLineageItem>>> = kotlin.runCatching{
        app.httpClient.request {
            url {
                takeFrom("https://lapis.cov-spectrum.org/gisaid/v1/sample/aggregated")
                parameters.append(PK_ACCESS_KEY,accessKey)
                parameters.append(PK_FIELDS, PV_FIELD_PANGO)
            }
            method = HttpMethod.Get
        }.body()
    }

    suspend fun getDateCount(
        accessKey: String,
        dateFrom:String,
        dateTo:String,
        queryCase: QueryCase,
        country:String? = null,
    ):Result<CommonApiBean<List<DateCountBean>>> = kotlin.runCatching{
        app.httpClient.request {
            url {
                takeFrom("https://lapis.cov-spectrum.org/gisaid/v1/sample/aggregated")
                parameters.apply {
                    append(PK_DATE_FROM,dateFrom)
                    append(PK_DATE_TO,dateTo)
                    append(PK_FIELDS, PV_FIELD_DATE)
                    append(PK_HOST, PV_HOST_HUMAN)

                    queryCase.apply {
                        nextcladePangoLineage?.let{ append(PK_NEXT_CLADE,it) }
                        variantQuery?.let { append(PK_VARIANT_QUERY,it) }
                        pangoLineage?.let { append(PK_PANGO,it) }

                        aaMutations.takeIf { it.isNotEmpty() }?.let{
                            append(PK_AA_M,it.reduce { s1, s2 -> "$s1,$s2" })
                        }
                        nucMutations.takeIf { it.isNotEmpty() }?.let{
                            append(PK_NUC_M,it.reduce { s1, s2 -> "$s1,$s2" })
                        }
                        aaInsertions.takeIf { it.isNotEmpty() }?.let{
                            append(PK_AA_I,it.reduce { s1, s2 -> "$s1,$s2" })
                        }
                        nucInsertions.takeIf { it.isNotEmpty() }?.let{
                            append(PK_NUC_I,it.reduce { s1, s2 -> "$s1,$s2" })
                        }
                    }

                    append(PK_ACCESS_KEY,accessKey)
                    country?.let{ append(PK_COUNTRY,it) }
                }
            }
            method = HttpMethod.Get
        }.also {
            println(it.request.url.toString())
        }.body()
    }
}